home *** CD-ROM | disk | FTP | other *** search
Text File | 1986-08-17 | 20.5 KB | 743 lines | [TEXT/MEDT] |
- /* A ROM Reference Desk Accessory */
- /* Frank Alviani */
- /* Version 1.1 */
- /* Pascal Format */
- /* 8:36:39 PM 8/5/86 */
- /* */
- /* Thanks to Don Melton for making */
- /* this a whole bunch easier! */
-
- #Options R=4 Z K
- #include <MacDefs.h>
- #include <QuickDraw.h>
- #include <Control.h>
- #include <TextEdit.h>
- #include <Dialog.h>
- #include <Menu.h>
- #include <Events.h>
- #include <Desk.h>
- #include <DeskAccessory.c>
- #include <Resource.h>
-
- /* MODIFIED DEFINITIONS
-
- *** IMPORTANT *** Other alternate elements of the OpParamType union structure
- are not defined here!!!
-
- The CntrlParam structure also must be defined because OSIO.h is not included.
- However, it remains unaltered. */
-
- #define OsType long
- union __OP
- {
- struct
- {
- short menuID;
- short menuItem;
- } menuData;
- Ptr event;
- };
-
- #define OpParamType union __OP
-
- struct __CP
- {
- struct __CP *ioLink;
- short ioType;
- short ioTrap;
- Ptr ioCmdAddr;
- ProcPtr ioCompletion;
- short ioResult;
- char *ioNamePtr;
- short ioVRefNum;
- short ioRefNum;
- short CSCode;
- OpParamType csp;
- };
-
- #define CntrlParam struct __CP
-
- typedef struct
- {
- char typeName[4];
- } ResType;
-
- typedef struct {
- long scrapSize;
- Handle scrapHandle;
- short scrapCount;
- short scrapState;
- char *scrapName;
- } ScrapStuff, *ScrapStuffPtr;
-
- #define NULL 0
- #define FALSE 0
- #define TRUE 1
- #define geneva 3
- #define NAMES_IN_BOX 7
- #define TIX ((long *) 0x16A)
-
- #define ACCEPT 1
- #define ACCEPT_CONT 2
- #define APPEND 3
- #define APPEND_CONT 4
- #define CANCEL 5
- #define NBOX 7
- #define SBAR 8
-
- #define FRONT_WINDOW -1
-
- /* SETUP DA HEADER AND GLUE ROUTINES
- *** IMPORTANT *** Invoke this macro BEFORE declaring any global variables or
- defining any Mac C functions!!!
-
- Macro parameters:
- 1 Name of desk accessory (enclose text in single quotes)
- 2 Resource ID of desk accessory (12-31 inclusive)
- 3 Flags
- 4 Delay
- 5 Event Mask
- 6 Request for global variable allocation: NeedGlobals or NoGlobals
- */
-
- #asm
-
- DeskAccessory 'Pas ROM Ref',12,$0400,0,$0142,NeedGlobals
-
- #endasm
-
- /* GLOBAL VARIABLES */
- short ownedID;
- short no_casting; /* 0=typecast 1=don't typecast */
- short mem_mash; /* 1=include "mashes memory" comment */
- short selection;
- MenuHandle hRRMenu;
- DialogPtr abtDlgPtr, mgrDlgPtr, rtnDlgPtr;
- long lastClick;
- short lastPick; /* used in double-click test */
- short data_refNum; /* vol ref num for data resource file */
- short old_v; /* for arrow-scrolling in dialog */
- ControlHandle rtnScrlH, namScrlH; /* scroll bar in routine window */
- ControlHandle vScrlH; /* "generic" for ModalDialog filterProc */
- Handle abTblH; /* handle to abbreviation table */
- TEHandle hTE; /* for names selection routine */
- Rect textR, TERect;
- char call[256]; /* sample here */
- ScrapStuffPtr sInfo;
-
- /*~Open/Close/Control~ --- Open Routine --- */
- short open(pb, dce)
- CntrlParam *pb;
- DeviceControl *dce;
- {
- GrafPtr oldPort;
- short item, type, err, def_vol;
- ControlHandle ctlH;
- Ptr tPtr;
- short pbCall();
-
- ownedID = 0xC000 - (32 * (1 + dce->dCtlRefNum));
- dce->dCtlMenu = ownedID;
-
- if (!dce->dCtlWindow)
- { hRRMenu = GetMenu(ownedID);
- HNoPurge(hRRMenu);
-
- if (!(mgrDlgPtr = (DialogPtr) NewPtr(sizeof(DialogRecord))))
- return -1;
- mgrDlgPtr = GetNewDialog(ownedID, mgrDlgPtr, FRONT_WINDOW);
- GetDItem(mgrDlgPtr, SBAR, &type, &namScrlH, &textR); /* scrollbar */
- namScrlH = NewControl(mgrDlgPtr, &textR, "\px", FALSE, 0, 0, 0,
- scrollBarProc, 0);
-
- if (!(rtnDlgPtr = (DialogPtr) NewPtr(sizeof(DialogRecord))))
- return -1;
- rtnDlgPtr = GetNewDialog(ownedID+1, rtnDlgPtr, FRONT_WINDOW);
-
- GetDItem(rtnDlgPtr, SBAR, &type, &rtnScrlH, &textR); /* scrollbar */
- rtnScrlH = NewControl(rtnDlgPtr, &textR, "\px", FALSE, 0, 0, 0,
- scrollBarProc, 0);
-
- GetDItem(rtnDlgPtr, NBOX, &type, &ctlH, &textR); /* get scrollBOX rect */
- TERect = textR;
- InsetRect(&TERect, 2, 2);
-
- if (!(abtDlgPtr = (DialogPtr) NewPtr(sizeof(DialogRecord))))
- return -1;
- abtDlgPtr = GetNewDialog(ownedID+2, abtDlgPtr, FRONT_WINDOW);
-
- /* open data file */
- if ((data_refNum = OpenResFile("\pRom Reference Data")) == -1)
- return -1;
-
- if ((abTblH = GetResource('ROMA', 1)) == NULL) /* get abb. table */
- return -1;
-
- no_casting = 0; mem_mash = 0;
- activate();
- }
- return 0;
- }
-
- /* --- Close --- */
- short close(pb, dce)
- CntrlParam *pb;
- DeviceControl *dce;
- {
- deActivate();
- ReleaseResource(hRRMenu);
- ReleaseResource(abTblH);
- DisposeDialog(mgrDlgPtr);
- DisposeDialog(rtnDlgPtr);
- DisposeDialog(abtDlgPtr);
- dce->dCtlWindow = (WindowPtr) NULL;
- CloseResFile(data_refNum); /* close data file */
- return 0;
- }
-
- /* --- Control --- */
- short control(pb, dce)
- CntrlParam *pb;
- DeviceControl *dce;
- {
- EventRecord *theEvent;
-
- switch (pb->CSCode)
- { case accEvent:
- theEvent = (EventRecord *) pb->csp.event;
- if (theEvent->what ==activateEvt)
- if (theEvent->modifiers & activeFlag)
- activate();
- break;
- case accMenu:
- doMenu(pb, pb->csp.menuData.menuItem, dce);
- break;
- }
- return 0;
- }
-
- activate()
- {
- (*hRRMenu)->menuID = ownedID;
- InsertMenu(hRRMenu, 0);
- DrawMenuBar();
- }
-
- deActivate()
- {
- DeleteMenu(ownedID);
- DrawMenuBar();
- }
-
- /*~Menu Stuff~ --- Handle Menu Invocations --- */
- doMenu(pb, menuItem, dce)
- CntrlParam *pb;
- short menuItem;
- DeviceControl *dce;
- {
- short theItem;
- GrafPtr tGPtr;
-
- switch (menuItem)
- { case 1: /* ABOUT */
- dce->dCtlFlags &= 0xFBFF; /* clear dCtlEnable */
- dce->dCtlFlags ^= 0x4000; /* set dNeedLock */
-
- ((WindowPeek) abtDlgPtr)->windowKind = 2; /* dialogkind */
- ShowWindow(abtDlgPtr);
- BringToFront(abtDlgPtr);
- SetPort(abtDlgPtr);
- ModalDialog(NULL, &theItem);
- ((WindowPeek) abtDlgPtr)->windowKind = dce->dCtlRefNum;
- HideWindow(abtDlgPtr);
-
- dce->dCtlFlags ^= 0x0400; /* set dCtlEnable */
- dce->dCtlFlags &= 0xBFFF; /* clear dNeedLock */
- break;
- case 2: /* LOOKUP CALLS */
- dce->dCtlFlags &= 0xFBFF; /* clear dCtlEnable */
- dce->dCtlFlags ^= 0x4000; /* set dNeedLock */
-
- findRtn(dce);
-
- dce->dCtlFlags ^= 0x0400; /* set dCtlEnable */
- dce->dCtlFlags &= 0xBFFF; /* clear dNeedLock */
- break;
- case 3: /* DISABLE TYPECASTING */
- if (no_casting) /* was NO, now YES */
- { no_casting = 0;
- CheckItem(hRRMenu, 3, FALSE);
- }
- else
- { no_casting = 1;
- CheckItem(hRRMenu, 3, TRUE);
- }
- break;
- case 4: /* INCLUDE 'MASHES MEMORY' COMMENT */
- if (mem_mash)
- { mem_mash = 0;
- CheckItem(hRRMenu, 4, FALSE);
- }
- else
- { mem_mash = 1;
- CheckItem(hRRMenu, 4, TRUE);
- }
- break;
- case 5: /* CLOSE */
- close(pb, dce);
- break;
- }
- HiliteMenu(0);
- }
-
- /*~Lookup Code~ --- Heart of the DA --- */
- findRtn(dce)
- DeviceControl *dce;
- {
- short the_manager, item, base_res_no, pick;
- long scrap_err, call_len;
- short BoxPick();
-
- get_mgr:
- /* use "select manager" dialog */
- dce->dCtlWindow = 0;
- /* get titles for selected manager */
- SetPort(mgrDlgPtr);
- item = BoxPick(mgrDlgPtr, namScrlH, 99, &the_manager, &base_res_no);
- HideWindow(mgrDlgPtr);
- if (item == CANCEL) return;
-
- /* get titles for selected manager */
- SetPort(rtnDlgPtr);
- item = BoxPick(rtnDlgPtr, rtnScrlH, the_manager+1, &pick, &base_res_no);
- if (item < CANCEL )
- { expandCall(base_res_no+pick, &call_len);
- if (call_len)
- { if (item < APPEND )
- { ZeroScrap();
- scrap_err = PutScrap((long) call_len, 'TEXT', call);
- }
- else
- AppendScrap((long) call_len, 'TEXT', call);
- }
- }
-
- ((WindowPeek) rtnDlgPtr)->windowKind = dce->dCtlRefNum;
- HideWindow(rtnDlgPtr);
-
- if (item == ACCEPT_CONT || item == APPEND_CONT) /* keep it up! */
- goto get_mgr;
- }
-
- /* --- assumes port is properly set before entry --- */
- /* --- returns item_no from modal dialog box --- */
- short BoxPick(dPtr, scrlH, resNo, sel, base)
- DialogPtr dPtr;
- ControlHandle scrlH;
- short resNo;
- short *sel; /* zero-based! */
- short *base;
- {
- short filter();
- Handle nameListH; /* handle to names-list resource */
- long call_len, nameList_len, ticks;
- short res_ct, done, item, l_no, sel_st, sel_en;
- Point pt;
-
- if ((nameListH = GetResource('ROMN', resNo)) == NULL)
- { SysBeep(60);
- return CANCEL;
- }
- nameList_len = SizeResource(nameListH);
- HLock(nameListH);
- res_ct = *((short *) *nameListH); /* ct of call resources */
- *base = *((short *) *nameListH+1); /* starting call res # is 2nd short! */
-
- hTE = TENew(&TERect, &TERect);
- (*hTE)->txFont = geneva;
- (*hTE)->crOnly = -1; /* CR breaks only */
- (*hTE)->txSize = 12;
- TESetText(*nameListH+4, nameList_len-4, hTE);
- TECalText(hTE);
- TESetSelect((*hTE)->lineStarts[0], (*hTE)->lineStarts[1], hTE);
-
- ((WindowPeek) dPtr)->windowKind = 2; /* dialogkind */
- ShowWindow(dPtr);
- BringToFront(dPtr);
- FrameRect(&textR.top);
- TEUpdate(&TERect.top, hTE);
- TEActivate(hTE);
- ShowControl(scrlH);
- SetCtlMin(scrlH, 0);
- if ((*hTE)->nLines > NAMES_IN_BOX) /* set up scrollbar */
- SetCtlMax(scrlH, (*hTE)->nLines-NAMES_IN_BOX);
- else
- SetCtlMax(scrlH, 0);
- SetCtlValue(scrlH, 0);
-
- done = FALSE; selection=0;
- old_v = 0;
- vScrlH = scrlH;
- while (!done)
- { ModalDialog(filter, &item); /* filter for keystrokes only */
- switch (item)
- { case ACCEPT:
- case ACCEPT_CONT:
- case APPEND:
- case APPEND_CONT:
- case CANCEL:
- done = TRUE;
- break;
- case NBOX:
- GetMouse(&pt);
- ticks = *TIX;
- l_no = (pt.v - textR.top) / (*hTE)->lineHeight; /* relative line# */
- selection = GetCtlValue(scrlH) + l_no;
- if ((lastClick + 30) > ticks)
- { item = ACCEPT; /* double click in same item */
- done = TRUE;
- break;
- }
- sel_st = (*hTE)->lineStarts[selection];
- if (selection >= res_ct)
- sel_en = 32767;
- else
- sel_en = (*hTE)->lineStarts[selection + 1];
- TESetSelect(sel_st, sel_en, hTE);
- TEActivate(hTE);
- lastPick = selection;
- lastClick = ticks;
- break;
- case SBAR:
- nameScroll(dPtr);
- break;
- }
- }
- TEDispose(hTE);
- HUnlock(nameListH);
- ReleaseResource(nameListH);
- *sel = selection;
- return item;
- }
-
- /* --- Append to scrap, updating scrapCount - Memory Only -- */
- /* assumes only 1 data type in desk scrap */
- AppendScrap(len, type, str)
- long len;
- long type; /* 4-char string */
- char *str;
- {
- long sSize, dSize;
-
- sInfo = (ScrapStuffPtr)0x960;
- if (sInfo->scrapState <= 0) return; /* can't do anything */
- sSize = GetHandleSize(sInfo->scrapHandle);
- dSize = *((long *)(*sInfo->scrapHandle) + 1); /* get existing len */
- SetHandleSize(sInfo->scrapHandle, sSize + len); /* make room */
- *((long *)(*sInfo->scrapHandle) + 1) = dSize + len;
- BlockMove(str, (*sInfo->scrapHandle + 8 + dSize), len);
- }
-
- /*~Scrolling~ --- Filter Events, Handle Scrolling, etc. --- */
- short filter(dPtr, ePtr, item)
- DialogPtr dPtr;
- EventRecord *ePtr;
- short *item;
- {
- #asm
- link A6,#0 ;no locals
- movem.l D1-D2,-(sp) ;save
- move.l 16(A6),D0
- move.l 12(A6),D1
- move.l 8(A6),D2
- jsr md_filter ;call C routine
- movem.l (SP)+,D1-D2
- unlk A6
- move.l (SP)+,A0 ;return addr
- add.l #12,sp
- move.b D0,(SP) ;return condition
- jmp (A0)
- #endasm
- }
-
- /* uses global "vScrlH" to access vertical scrollbar in MD window */
- short md_filter(dPtr, ePtr, item)
- DialogPtr dPtr;
- EventRecord *ePtr;
- short *item;
- {
- short part, new_v, i, j, k, dV;
- short sel_st, sel_en, delta;
- char ch, ch2, key;
- Ptr tPtr, base;
- short nameScroll();
-
- switch(ePtr->what)
- { case mouseDown:
- return FALSE; /* handle normally */
- break;
- case autoKey:
- case keyDown: /* select by 1st letter, cursor keys, etc. */
- ch = ePtr->message & 0xFF;
- if (ch==0x03 || ch==0x0D) /* enter or return */
- { *item = 1; /* accept */
- return TRUE;
- }
- /* check for up/down arrow keys */
- if (old_v <= GetCtlMax(vScrlH)) /* don't update if in last paneful */
- old_v = GetCtlValue(vScrlH);
- j = GetCtlMax(vScrlH);
- TEDeactivate(hTE);
- TESetSelect(0, 0, hTE);
- key = (ePtr->message & 0xFF00) >> 8;
- if (key == 0x4D) /* up arrow on Mac+ */
- { i = old_v-1;
- if (i < 0) i = 0;
- goto qa1;
- }
- if (key == 0x48) /* down arrow on Mac+ */
- { i = old_v + 1;
- goto qa1;
- }
- /* look up 1st entry starting with given key or higher */
- ch &= (~0x20); /* force uppercase */
- HLock((*hTE)->hText); /* lock text for examination */
- base = *(*hTE)->hText;
- for (i=0;i<j;i++)
- { tPtr = base + (*hTE)->lineStarts[i];
- ch2 = *tPtr & (~0x20); /* 1st char of line, upper-cased */
- if (ch2 >= ch) /* found desired line */
- break;
- }
- HUnlock((*hTE)->hText);
- qa1:
- if (i <= j) /* in normal range, scroll */
- { dV = (old_v - i) * (*hTE)->lineHeight;
- SetCtlValue(vScrlH, i);
- TEScroll(0, dV, hTE);
- }
-
- if (i >= GetCtlMax(vScrlH)+NAMES_IN_BOX)
- { i = GetCtlMax(vScrlH)+NAMES_IN_BOX-1; /* can't go too far */
- sel_en = 32767;
- k = (*hTE)->nLines-1;
- sel_st = (*hTE)->lineStarts[k];
- }
- else
- { sel_en = (*hTE)->lineStarts[i+1];
- sel_st = (*hTE)->lineStarts[i];
- }
- TESetSelect(sel_st, sel_en, hTE);
- old_v = i;
- selection = i; /* in global so ACCEPT works */
- TEActivate(hTE);
- return TRUE;
- break;
- default:
- return FALSE;
- break;
- }
- }
-
- void nameScroll(dPtr)
- DialogPtr dPtr;
- {
- short part, new_part, old_v, new_v, dV;
- ControlHandle ctlH;
- Point pt;
- void scroll_up(), scroll_dn();
-
- GetMouse(&pt);
- if (part = FindControl(&pt, dPtr, &ctlH))
- { old_v = GetCtlValue(ctlH);
- switch (part)
- { case inThumb:
- new_part = TrackControl(ctlH, &pt, NULL);
- if (new_part == part) /* redraw box */
- { TEDeactivate(hTE);
- new_v = GetCtlValue(ctlH);
- dV = (old_v - new_v) * (*hTE)->lineHeight;
- TEScroll(0, dV, hTE);
- }
- break;
- case inUpButton:
- TrackControl(ctlH, &pt, scroll_up);
- break;
- case inDownButton:
- TrackControl(ctlH, &pt, scroll_dn);
- break;
- case inPageUp:
- new_v = old_v - (NAMES_IN_BOX-1);
- if (old_v-new_v < 0)
- { dV = old_v * (*hTE)->lineHeight; /* stop at beginning */
- SetCtlValue(ctlH, 0);
- }
- else
- { dV = (NAMES_IN_BOX-1) * (*hTE)->lineHeight;
- SetCtlValue(ctlH, new_v);
- }
- TEScroll(0, dV, hTE);
- break;
- case inPageDown:
- new_v = old_v + (NAMES_IN_BOX-1);
- if (new_v > GetCtlMax(ctlH))
- { dV = -(GetCtlMax(ctlH) - old_v) * (*hTE)->lineHeight;
- SetCtlValue(ctlH, GetCtlMax(ctlH));
- }
- else
- { dV = -(NAMES_IN_BOX-1) * (*hTE)->lineHeight;
- SetCtlValue(ctlH, new_v);
- }
- TEScroll(0, dV, hTE);
- break;
- }
- selection = new_v = GetCtlValue(ctlH);
- TESetSelect((*hTE)->lineStarts[new_v], (*hTE)->lineStarts[new_v+1], hTE);
- TEActivate(hTE);
- }
- }
-
- void my_scroll_up(theControl, part)
- ControlHandle theControl;
- short part;
- {
- short v;
-
- if (part == inUpButton) /* */
- { v = GetCtlValue(theControl);
- if (v == 0) return;
- SetCtlValue(theControl, v-1);
- TEScroll(0, (*hTE)->lineHeight, hTE);
- }
- return;
- #asm
- scroll_up:
- MOVE.L (SP)+,A0 ;RETURN
- MOVE.W (SP)+,D1 ;PART
- MOVE.L (SP)+,D0 ;CTL HANDLE
- MOVE.L A0,-(SP)
- MOVEM.L A3-A4/D3-D7,-(SP)
- JSR my_scroll_up
- MOVEM.L (SP)+,A3-A4/D3-D7
- RTS
- #endasm
- }
-
- void my_scroll_dn(theControl, part)
- ControlHandle theControl;
- short part;
- {
- short v;
-
- if (part == inDownButton)
- { v = GetCtlValue(theControl);
- if (v == GetCtlMax(theControl)) return;
- SetCtlValue(theControl, v+1);
- TEScroll(0, -(*hTE)->lineHeight, hTE);
- }
- return;
- #asm
- scroll_dn:
- MOVE.L (SP)+,A0 ;RETURN
- MOVE.W (SP)+,D1 ;PART
- MOVE.L (SP)+,D0 ;CTL HANDLE
- MOVE.L A0,-(SP)
- MOVEM.L A3-A4/D3-D7,-(SP)
- JSR my_scroll_dn
- MOVEM.L (SP)+,A3-A4/D3-D7
- RTS
- #endasm
- }
-
- /*~Prototype Expansion~ --- Resource -> usable call --- */
- void expandCall(res_no, len)
- short res_no;
- long *len;
- {
- Handle rHndl;
- short i, j, isVar, cast;
- long rSize;
- unsigned char *rPtr, ch, abb[32];
-
- if ((rHndl = GetResource('ROMC', res_no)) == NULL)
- { SysBeep(30);
- *len = 0; *call = NULL;
- return;
- }
- rSize = SizeResource(rHndl);
- HLock(rHndl);
- rPtr = (unsigned char *) *rHndl;
- HLock(abTblH); /* lock abb. table */
-
- /* deal with "memory mashing" */
- j=0; isVar = 0; cast = NULL;
- if (mem_mash)
- { if (*(rPtr++)) /* this one moves memory */
- appStr("{ mashes memory } ", call, &j)
- }
- else
- rPtr += 1; /* just skip flag */
-
- for (i=1;i<rSize;i++) /* copy into output, expanding abbreviations */
- { if (*rPtr < 0x80) /* normal char */
- { /* end of param? */
- if (*rPtr == ',' || *rPtr == ')' || *rPtr == ' ' || *rPtr == '=')
- { if (no_casting == NULL && cast)
- { call[j++] = ':';
- findabb(cast, abb); /* lookup typecast */
- appStr(abb, &(call[j]), &j);
- cast = NULL; /* done with it */
- }
- }
- call[j++] = *(rPtr++);
- continue;
- }
- if (no_casting == NULL)
- { if (*rPtr >= 0xC0) /* "var" */
- { cast = *rPtr - 0x40;
- appStr("VAR ", &(call[j]), &j);
- }
- else
- cast = *rPtr;
- }
- rPtr += 1;
- }
-
- appStr(";\n", &(call[j]), &j);
- *len = j;
- HUnlock(rHndl);
- HUnlock(abTblH);
- ReleaseResource(rHndl);
- }
-
- void appStr(src, target, tLen)
- char *src; /* string copied FROM, null-terminated */
- char *target; /* string appended TO */
- short *tLen; /* initial length of target; updated */
- {
- long ct=0;
- Ptr tp;
-
- tp = src;
- while (*(tp++))
- ct++;
- BlockMove(src, target, ct);
- *tLen = *tLen + ct;
- }
-
- void findabb(c, dest)
- unsigned char c;
- unsigned char *dest;
- {
- short i,j;
- Ptr tPtr;
-
- tPtr = *abTblH;
- j = c - 0x80;
- for (i=0;i<j;i++)
- while (*(tPtr++));
- while (*tPtr)
- *(dest++) = *(tPtr++);
- *dest = NULL;
- }
-